Crate keyring

source ·
Expand description

§Keyring

This is a cross-platform library that does storage and retrieval of passwords (or other secrets) in an underlying platform-specific secure store. A top-level introduction to the library’s usage, as well as a small code sample, may be found in the library’s entry on crates.io. Currently supported platforms are Linux, FreeBSD, OpenBSD, Windows, macOS, and iOS.

§Design

This crate implements a very simple, platform-independent concrete object called an entry. Each entry is identified by a <service name, user name> pair of UTF-8 strings, optionally augmented by a target string (which can be used to distinguish two entries that have the same service name and user name). Entries support setting, getting, and forgetting (aka deleting) passwords (UTF-8 strings).

Entries provide persistence for their passwords by wrapping credentials held in platform-specific credential stores. The implementations of these platform-specific stores are captured in two types (with associated traits):

  • a credential builder, represented by the CredentialBuilder type (and CredentialBuilderApi trait). Credential builders are given the identifying information provided for an entry and maps it to the identifying information for a matching platform-specific credential.
  • a credential, represented by the Credential type (and CredentialApi trait). The platform-specific credential identified by a builder for an entry is what provides the secure storage for that entry’s password.

§Crate-provided Credential Stores

This crate runs on several different platforms, and it provides one or more implementations of credential stores on each platform. These implementations work by mapping the data used to identify an entry to data used to identify platform-specific storage objects. For example, on macOS, the service and user names provided for an entry are mapped to the service and user attributes that identify an element in the macOS keychain.

Typically, platform-specific stores have a richer model of an entry than the one used by this crate. They expose their specific model in the concrete credential objects they use to implement the Credential trait. In order to allow clients to access this richer model, the Credential trait has an as_any method that returns a reference to the underlying concrete object typed as Any, so that it can be downgraded to its concrete type.

§Client-provided Credential Stores

In addition to the platform stores implemented by this crate, clients are free to provide their own secure stores and use those. There are two mechanisms provided for this:

  • Clients can give their desired credential builder to the crate for use by the Entry::new and Entry::new_with_target calls. This is done by making a call to set_default_credential_builder. The major advantage of this approach is that client code remains independent of the credential builder being used.
  • Clients can construct their concrete credentials directly and then turn them into entries by using the Entry::new_with_credential call. The major advantage of this approach is that credentials can be identified however clients want, rather than being restricted to the simple model used by this crate.

§Mock Credential Store

In addition to the platform-specific credential stores, this crate also provides a mock credential store that clients can use to test their code in a platform independent way. The mock credential store allows for pre-setting errors as well as password values to be returned from Entry method calls.

§Interoperability with Third Parties

Each of the credential stores provided by this crate uses an underlying platform-specific store that may also be used by modules written in other languages. If you want to interoperate with these third party credential writers, then you will need to understand the details of how the target, service name, and user name of this crate’s generic model are used to identify credentials in the platform-specific store. These details are in the implementation of this crate’s secure-storage modules, and are documented in the headers of those modules.

(N.B. Since the included credential store implementations are platform-specific, you may need to use the Platform drop-down on docs.rs to view the storage module documentation for your desired platform.)

§Caveats

This module manipulates passwords as UTF-8 encoded strings, so if a third party has stored an arbitrary byte string then retrieving that password will return a BadEncoding error. The returned error will have the raw bytes attached, so you can access them.

While this crate’s code is thread-safe, accessing the same entry from multiple threads in close proximity may be unreliable (especially on Windows), in that the underlying platform store may actually execute those calls in a different order than they are made. As long as you access a single entry from only one thread at a time, multi-threading should be fine.

(N.B. Creating an entry is not the same as accessing it, because entry creation doesn’t go through the platform credential manager. It’s fine to create an entry on one thread and then immediately use it on a different thread. This is thoroughly tested on all platforms.)

Re-exports§

Modules§

  • Platorm-independent secure storage model
  • Platform-independent error model.
  • Linux kernel (keyutils) credential store
  • Mock credential store
  • secret-service credential store

Structs§

Functions§